//*****************************************************************************
// JFab (http://code.google.com/p/jfab)
// Copyright (c) 2011-2012 JFab.org
// Admin jfab@jeffreythompson.net
//
// See the file "LICENSE.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//*****************************************************************************

package org.jfab.core.io;

import java.io.Writer;

import org.apache.commons.collections.CollectionUtils;
import org.jfab.core.collection.CGConstructorList;
import org.jfab.core.collection.CGInitializationBlockList;
import org.jfab.core.collection.CGMethodList;
import org.jfab.core.factory.StringFactory;
import org.jfab.core.factory.TypeReferenceSupport;
import org.jfab.core.formatter.Formatter;
import org.jfab.core.model.CGCompilationUnit;
import org.jfab.core.model.CGConstructor;
import org.jfab.core.model.CGField;
import org.jfab.core.model.CGMethod;

/**
 * Provides a partial implementation of a concrete unit writer.
 * 
 * @param <T> Code generator object type.
 */
public abstract class CGConcreteUnitWriter<T extends CGCompilationUnit> extends
        CGCompilationUnitWriter<T>
{
    /** Method writer. */
    private final CGWriter<CGMethod> _methodWriter;

    /** Constructor writer. */
    private final CGWriter<CGConstructor> _constructorWriter;

    /** Initialization block writer. */
    private final CGInitializationBlockWriter _initializationBlockWriter;

    /**
     * Construct this object with the given parameters.
     * 
     * @param typeReferenceSupport Type reference support.
     * @param stringFactory String factory.
     * @param basicCodeGenerator Basic code generator.
     * @param fieldWriter Field writer.
     * @param formatter Code formatter.
     * 
     * @param initializationBlockWriter Initialization block writer.
     * @param constructorWriter Constructor writer.
     * @param methodWriter Method writer.
     */
    public CGConcreteUnitWriter(
            final TypeReferenceSupport typeReferenceSupport,
            final StringFactory stringFactory,
            final BasicCodeGenerator basicCodeGenerator,
            final CGWriter<CGField> fieldWriter, final Formatter formatter,
            final CGInitializationBlockWriter initializationBlockWriter,
            final CGWriter<CGConstructor> constructorWriter,
            final CGWriter<CGMethod> methodWriter)
    {
        super(typeReferenceSupport, stringFactory, basicCodeGenerator,
                fieldWriter, formatter);

        _initializationBlockWriter = initializationBlockWriter;
        _constructorWriter = constructorWriter;
        _methodWriter = methodWriter;
    }

    /**
     * @return the constructorWriter
     */
    protected CGWriter<CGConstructor> getConstructorWriter()
    {
        return _constructorWriter;
    }

    /**
     * @return the initializationBlockWriter
     */
    protected CGInitializationBlockWriter getInitializationBlockWriter()
    {
        return _initializationBlockWriter;
    }

    /**
     * @return the methodWriter
     */
    protected CGWriter<CGMethod> getMethodWriter()
    {
        return _methodWriter;
    }

    /**
     * Write constructors.
     * 
     * @param writer Writer.
     * @param constructors Constructors.
     */
    protected void writeConstructors(final Writer writer,
            final CGConstructorList constructors)
    {
        if (CollectionUtils.isNotEmpty(constructors))
        {
            for (final CGConstructor cgConstructor : constructors)
            {
                getBasicCodeGenerator().writeBlankLine(writer);
                getConstructorWriter().write(writer, cgConstructor);
            }
        }
    }

    /**
     * Write initialization blocks.
     * 
     * @param writer Writer.
     * @param initializationBlocks Initialization blocks.
     */
    protected void writeInitializationBlocks(final Writer writer,
            final CGInitializationBlockList initializationBlocks)
    {
        if (CollectionUtils.isNotEmpty(initializationBlocks))
        {
            final int size = initializationBlocks.size();

            for (int i = 0; i < size; i++)
            {
                if (i > 0)
                {
                    getBasicCodeGenerator().writeBlankLine(writer);
                }

                getInitializationBlockWriter().write(writer,
                        initializationBlocks.get(i));
            }
        }
    }

    /**
     * Write methods.
     * 
     * @param writer Writer.
     * @param methods Methods.
     */
    protected void writeMethods(final Writer writer, final CGMethodList methods)
    {
        if (CollectionUtils.isNotEmpty(methods))
        {
            for (final CGMethod cgMethod : methods)
            {
                getBasicCodeGenerator().writeBlankLine(writer);
                getMethodWriter().write(writer, cgMethod);
            }
        }
    }
}
